package com.yanqu.road.server.gameplayer.module.activity.pawnshop;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.pawnshop.*;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.enums.activity.pawnshop.*;
import com.yanqu.road.logic.bussiness.activity.PawnshopBussiness;
import com.yanqu.road.pb.activity.PawnshopProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.pawnshop.PawnshopMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.pb.PawnshopPb;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class PawnshopModule extends GeneralModule {

    /**
     * 玩家的当铺数据
     **/
    private UserPawnshop userPawnshop = null;
    /**
     * 玩家的当铺事件数据
     **/
    private Map<Long, UserPawnshopEvent> userPawnshopEventMap = new ConcurrentHashMap<>();
    private UserPawnshopEvent userPawnshopEvent = null;
    /**
     * 玩家的当铺物件数据
     **/
    private Map<Long, UserPawnshopItem> userPawnshopItemMap = new HashMap<>();
    /**
     * 玩家的当铺弹窗数据
     **/
    private Map<Long, UserPawnshopNotify> userPawnshopNotifyMap = new HashMap<>();

    private RandomHelper random = new RandomHelper();

    private AtomicLong curNotifyId = new AtomicLong(0);

    public PawnshopModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        if (SystemOpenMgr.systemOpen(player, eSystemId.PawnshopActivity.getValue())) {
            // 获取进行中的活动信息
            List<ActivityInfo> openActivityInfoList = NormalActivityMgr
                    .getOpenActivityInfoList(eActivityType.PawnshopActivity.getValue());
            if (openActivityInfoList.isEmpty()) {
                return true;
            }
            int activityId = openActivityInfoList.get(0).getActivityId();
            if (activityId > 0) {
                userPawnshop = PawnshopBussiness.getUserPawnshop(player.getUserId(), activityId);
                if (userPawnshop != null) {
                    userPawnshopEvent = PawnshopBussiness.getUserPawnshopEvent(player.getUserId(), activityId);
                    userPawnshopItemMap = PawnshopBussiness.getUserPawnshopItemMap(player.getUserId(), activityId);
                    curNotifyId = new AtomicLong(PawnshopBussiness.getMaxUserPawnshopNotifyId(player.getUserId(), activityId));
                    userPawnshopNotifyMap = getNotifyMapFromDb(activityId);

                }
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        if (SystemOpenMgr.systemOpen(player, eSystemId.PawnshopActivity.getValue())) {
            // 初始化玩家数据
            List<ActivityInfo> openActivityInfoList = NormalActivityMgr
                    .getOpenActivityInfoList(eActivityType.PawnshopActivity.getValue());
            if (openActivityInfoList.isEmpty()) {
                return true;
            }
            if (userPawnshop == null) {
                initUserData();
            }
            if (userPawnshopEvent != null) {
                userPawnshopEventMap.put(userPawnshopEvent.getEventId(), userPawnshopEvent);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        if (userPawnshop != null) {
            if (userPawnshop.isReception() && userPawnshopEvent == null) {
                userPawnshop.setReception(false);
            }
            // 同步配置
            loginSendPower();
        }
    }

    @Override
    public boolean saveData() {
        if (userPawnshop != null) {
            if (userPawnshop.isInsertOption()) {
                PawnshopBussiness.addUserPawnshop(userPawnshop);
            } else if (userPawnshop.isUpdateOption()) {
                PawnshopBussiness.updateUserPawnshop(userPawnshop);
            }
        }
        if (userPawnshopEventMap != null) {
            for (UserPawnshopEvent event : new ArrayList<>(userPawnshopEventMap.values())) {
                if (event.isInsertOption()) {
                    PawnshopBussiness.addUserPawnshopEvent(event);
                } else if (event.isUpdateOption()) {
                    PawnshopBussiness.updateUserPawnshopEvent(event);
                }
            }
        }
        if (userPawnshopItemMap != null) {
            for (UserPawnshopItem userItem : userPawnshopItemMap.values()) {
                if (userItem.isInsertOption()) {
                    PawnshopBussiness.addUserPawnshopItem(userItem);
                } else if (userItem.isUpdateOption()) {
                    PawnshopBussiness.updateUserPawnshopItem(userItem);
                }
            }
        }
        if (userPawnshopNotifyMap != null) {
            for (UserPawnshopNotify userNotify : userPawnshopNotifyMap.values()) {
                if (userNotify.isInsertOption()) {
                    PawnshopBussiness.addUserPawnshopNotify(userNotify);
                } else if (userNotify.isUpdateOption()) {
                    PawnshopBussiness.updateUserPawnshopNotify(userNotify);
                }
            }
        }
        return true;
    }

    private Map<Long, UserPawnshopNotify> getNotifyMapFromDb(int activityId) {
        Map<Long, UserPawnshopNotify> notifyMap = PawnshopBussiness.getUserPawnshopNotifyMap(player.getUserId(), activityId);
        for (UserPawnshopNotify userPawnshopNotify : notifyMap.values()) {
            UserPawnshopItem userPawnshopItem = getUserPawnshopItem(userPawnshopNotify.getItemId());
            userPawnshopNotify.setUserPawnshopItem(userPawnshopItem);
        }
        return notifyMap;
    }

    /**
     * 获取活动ID
     *
     * @return
     */
    public int getActivityId() {
        return userPawnshop == null ? 0 : userPawnshop.getActivityId();
    }

    public UserPawnshop getUserPawnshop() {
        return userPawnshop;
    }

    public UserPawnshopEvent getUserPawnshopEvent() {
        return userPawnshopEvent;
    }

    /**
     * 初始化玩家数据
     */
    public synchronized void initUserData() {
        int activityId = PawnshopMgr.getShowTimeActivityId();
        if (userPawnshop != null && userPawnshop.getActivityId() == activityId) {
            return;
        }
        userPawnshopEventMap = new ConcurrentHashMap<>();
        userPawnshopItemMap = new ConcurrentHashMap<>();
        curNotifyId = new AtomicLong(0);

        // 初始当铺等级1
        int levelPS = 1;
        // 初始赠送的当铺币
        long coinInit = PawnshopMgr.config.initCoin;
        // 生成当铺数据
        userPawnshop = new UserPawnshop();
        userPawnshop.setUserId(player.getUserId());
        userPawnshop.setActivityId(activityId);
        userPawnshop.setLvReward(1);
        userPawnshop.setReceptionNum(0);
        userPawnshop.setLevel(levelPS);
        userPawnshop.setCoinUsable(coinInit);
        userPawnshop.setWashTimes(0);
        userPawnshop.setStaminaUsable(PawnshopMgr.config.staminaInit);
        userPawnshop.setLastRestoreTime(System.currentTimeMillis() / 1000);
        userPawnshop.setPoliticsEventId(0);
        userPawnshop.setPoliticsAddition(0);
        userPawnshop.setPoliticsStartReceptionNum(0);
        userPawnshop.setPoliticsTriggerRate(PawnshopMgr.config.getPoliticsDefaultRate());
        userPawnshop.setNpcIcon(randomNpcIcon());
        userPawnshop.setInsertOption();

        // 生成初始的赠送物件
        List<Long> itemIdList = createStartItems(levelPS, activityId);
        notifyScoreChange();
    }

    /**
     * 接待完成触发
     */
    public void afterReception() {
        userPawnshop.setNpcIcon(randomNpcIcon());
        userPawnshop.setReception(false);
        if (userPawnshopEvent != null) {
            userPawnshopEvent.setFinish(true);
        }
        userPawnshopEvent = null;
        //增加接待次数
        userPawnshop.setReceptionNum(userPawnshop.getReceptionNum() + 1);
        //增加经营进度
        if (userPawnshop.getReceptionNum() % PawnshopMgr.config.getReceptionDay() == 0) {//过完一天
            //当铺升级
            checkPawnshopUpgrade();
            //员工升级
            checkStaffUpgrade();
            userPawnshop.setWashTimes(0);
            player.notifyListener(eGamePlayerEventType.PawnshopOperateDays.getValue(), 1);
        }
        //时事触发
        checkPolitics();
        //检测各物件状态
        checkItemOpStatus(0);
        //财富变更
        notifyScoreChange();
    }

    public void createNewEvent(int eventType) {
        int activityId = PawnshopMgr.getShowTimeActivityId();
        int levelPS = userPawnshop.getLevel();
        eventType = randomEventType(null);
        UserPawnshopEvent event = createEvent(levelPS, eventType, activityId);
        if (eventType == ePawnshopEventType.Buy.getValue() && userPawnshop.getCoinUsable() < event.getNpcBid()) {
            List<ePawnshopEventType> list = new ArrayList<>();
            list.add(ePawnshopEventType.Buy);
            eventType = randomEventType(list);
            event = createEvent(levelPS, eventType, activityId);
        }
        this.userPawnshopEvent = event;
        this.userPawnshopEvent.setStatus(ePawnshopEventStatusType.NORMAL.getValue());
        userPawnshopEventMap.put(userPawnshopEvent.getEventId(), userPawnshopEvent);
    }

    /**
     * 随机事件
     *
     * @param list
     * @return
     */
    private int randomEventType(List<ePawnshopEventType> list) {
        Set<ePawnshopEventType> eventTypeSet = new HashSet<>(Arrays.asList(ePawnshopEventType.values()));
        int num = getAllItemCount();
        ConfPawnshop confPawnshop = PawnshopMgr.config.getConfPawnshop(userPawnshop.getLevel());
        // 总财富少于配置值， 必定送钱事件
        long moneyTriggerBound = confPawnshop.getMoneyTriggerBound();
        if (getTotalWealth() < moneyTriggerBound) {
            return ePawnshopEventType.Money.getValue();
        }
        int itemCount = confPawnshop.getItemCount();
        if (num >= itemCount) {
            //货架已满
            eventTypeSet.remove(ePawnshopEventType.Buy);
            eventTypeSet.remove(ePawnshopEventType.Hock);
            eventTypeSet.remove(ePawnshopEventType.Gemstone);
        }
        if (getCanSellItemCount() <= 0) {
            eventTypeSet.remove(ePawnshopEventType.Sell);
        }
        if (list != null) {
            for (ePawnshopEventType eventType : list) {
                eventTypeSet.remove(eventType);
            }
        }
        Map<ePawnshopEventType, Integer> eventWeightMap = new HashMap<>();
        int totalWeight = 0;
        for (ePawnshopEventType eventType : eventTypeSet) {
            Integer weight = PawnshopMgr.config.eventWeightList.get(eventType.getValue() - 1);
            if (eventType == ePawnshopEventType.Sell && PawnshopMgr.isSellEventDoubleWeight(userPawnshop.getCoinUsable(), getItemWealth())) {
                // 某种条件下 售卖事件概率翻倍
                weight *= 2;
            }
            eventWeightMap.put(eventType, weight);
            totalWeight += weight;
        }


        int randomNum = random.next(0, totalWeight);
        for (Map.Entry<ePawnshopEventType, Integer> entry : eventWeightMap.entrySet()) {
            Integer weight = entry.getValue();
            if (randomNum < weight) {
                return entry.getKey().getValue();
            }
            randomNum -= weight;
        }
        return 0;
    }

    private int getAllItemCount() {
        int num = 0;
        for (UserPawnshopItem item : userPawnshopItemMap.values()) {
            if (item.getOpStatus() != ePawnshopOpStatus.SellOut.getValue()) {
                num++;
            }
        }
        return num;
    }

    public String randomNpcIcon() {
        return PawnshopMgr.config.randomNpcIcon();
    }

    /**
     * 生成事件
     */
    private UserPawnshopEvent createEvent(int levelPS, int eventType, int activityId) {
        // 事件ID=生成时的时间戳
        long eventId = System.currentTimeMillis();
        UserPawnshopEvent userPawnshopEvent = new UserPawnshopEvent();
        userPawnshopEvent.setUserId(player.getUserId());
        userPawnshopEvent.setActivityId(activityId);
        userPawnshopEvent.setEventId(eventId);
        userPawnshopEvent.setType(eventType);
        userPawnshopEvent.setPatient(100);
        // 生成NPC数据
        PawnshopNpc npc = new PawnshopNpc();
        npc.setLv(PawnshopMgr.randomNpcLv(eventType, userPawnshop.getLevel()));
        userPawnshopEvent.setNpc(npc);
        // 生成物件数据
        if (eventType == ePawnshopEventType.Sell.getValue() || eventType == ePawnshopEventType.Buy.getValue()) {
            // 生成1个物件
            List<PawnshopItem> itemList = new ArrayList<>();

            PawnshopItem item;
            if (eventType == ePawnshopEventType.Buy.getValue()) {
                long itemId = System.currentTimeMillis();
                // 先判断是假货事件 如果是假货事件 词条生成就走 伪造的配置
                userPawnshopEvent.setIsFake(PawnshopMgr.randomFake(eventType));
                int fakeStar = 0;
                if (userPawnshopEvent.getIsFake()) {
                    fakeStar = PawnshopMgr.randomFakeStar();
                }
                item = PawnshopMgr.createItem(itemId, levelPS, ePawnshopItemType.Item, userPawnshop, fakeStar,false);
                item.setFakeStar(fakeStar);
            } else {
                item = getCanSellItem();
                UserPawnshopItem userPawnshopItem = userPawnshopItemMap.get(item.getItemId());
                int fakeStar = userPawnshopItem.getFakeStar();
                userPawnshopEvent.setIsFake(PawnshopMgr.sellFakeSeeThrough(fakeStar));
            }
            itemList.add(item);
            userPawnshopEvent.setItemList(itemList);
            userPawnshopEvent.setWashTime(0);
            userPawnshopEvent.setUserBid(0);
            List<PawnshopBidPrice> bidPriceList;
            long valuationPrice = PawnshopMgr.calcItemValuationPrice(item, userPawnshop.getPoliticsAddition(), getModValue());
            userPawnshopEvent.setValuationPrice(valuationPrice);
            if (eventType == ePawnshopEventType.Sell.getValue()) {
                userPawnshopEvent.setNpcBid(PawnshopMgr.initSellFirstPrice(userPawnshop, userPawnshopEvent));
                userPawnshopEvent.setMaxPrice(PawnshopMgr.initSellMaxPrice(userPawnshop, userPawnshopEvent));
                //第一次出价 需要现有最高价格
                userPawnshopEvent.setNpcWantPrice(PawnshopMgr.initSellWantPrice(userPawnshop, userPawnshopEvent));
                bidPriceList = PawnshopMgr.sellBidPriceList(userPawnshop, userPawnshopEvent);
            } else {
                userPawnshopEvent.setNpcBid(PawnshopMgr.initBuyFirstPrice(userPawnshop, userPawnshopEvent));
                userPawnshopEvent.setMaxPrice(PawnshopMgr.initBuyMaxPrice(userPawnshop, userPawnshopEvent));
                //第一次出价 需要现有最高价格
                userPawnshopEvent.setNpcWantPrice(PawnshopMgr.initBuyWantPrice(userPawnshop, userPawnshopEvent));
                bidPriceList = PawnshopMgr.buyBidPriceList(userPawnshop, userPawnshopEvent);
            }
            userPawnshopEvent.setPriceList(bidPriceList);

        } else if (eventType == ePawnshopEventType.Hock.getValue()) {
            // 生成1个物件
            List<PawnshopItem> itemList = new ArrayList<>();
            long itemId = System.currentTimeMillis();
            PawnshopItem itemJSON = PawnshopMgr.createItem(itemId, levelPS, ePawnshopItemType.Item, userPawnshop, 0, false);
            itemList.add(itemJSON);
            userPawnshopEvent.setItemList(itemList);
        } else if (eventType == ePawnshopEventType.Gemstone.getValue()) {
            // 生成2个玉石
            List<PawnshopItem> itemList = new ArrayList<>();
            String firstDescNo = "";
            boolean special = false;
            if (PawnshopMgr.canTriggerSpecialEvent(userPawnshop.getActivityId(),userPawnshop.getUserId())) {
                special = true;
            }
            for (int i = 0; i < 2; i++) {
                long itemId = System.currentTimeMillis() + i;
                PawnshopItem item = PawnshopMgr.createItem(itemId, levelPS, ePawnshopItemType.Gemstone, userPawnshop, 0,special);
                long valuationPrice = PawnshopMgr.calcItemValuationPrice(PawnshopMgr.calcBasePrice(item.getStoneLv()), 0, 0, 0, 0, userPawnshop.getPoliticsAddition(), getModValue());
                userPawnshopEvent.setValuationPrice(valuationPrice);
                itemList.add(item);
                long firstPrice = PawnshopMgr.initStonePrice(userPawnshop, userPawnshopEvent.getNpc().getLv(), valuationPrice);
                item.setCoinBuy(firstPrice);
                if (i == 0) {
                    firstDescNo = item.getDescNo();
                } else {
                    if (firstDescNo.equals(item.getDescNo())) {
                        for (int j = 0; j < 100; j++) {
                            String s = PawnshopMgr.randomItemDesc(item.getStoneGoodsId());
                            if (!firstDescNo.equals(s)) {
                                item.setDescNo(s);
                                break;
                            }
                        }
                    }
                }
            }
            userPawnshopEvent.setItemList(itemList);
        } else if (eventType == ePawnshopEventType.Money.getValue()) {
            // 送钱事件数据
            userPawnshopEvent.setMoney(PawnshopMgr.config.createMoneyJSON(levelPS));
        }
        userPawnshopEvent.setInsertOption();
        if (this.userPawnshopEvent != null) {
            this.userPawnshopEvent.setFinish(true);
        }
        userPawnshopEvent.setInsertOption();
        return userPawnshopEvent;
    }

    public long getModValue() {
        return 1;
    }

    public int getCanSellItemCount() {
        int num = 0;
        for (UserPawnshopItem item : userPawnshopItemMap.values()) {
            if (item.getOpStatus() == ePawnshopOpStatus.Default.getValue()) {
                num++;
            }
        }
        return num;
    }

    private PawnshopItem getCanSellItem() {
        List<UserPawnshopItem> list = new ArrayList<>();
        for (UserPawnshopItem item : userPawnshopItemMap.values()) {
            if (item.getOpStatus() == ePawnshopOpStatus.Default.getValue()) {
                list.add(item);
            }
        }
        int next = random.next(0, list.size());
        UserPawnshopItem item = list.get(next);
        PawnshopItem pawnshopItem = new PawnshopItem();
        try {
            BeanUtils.copyProperties(pawnshopItem, item);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return pawnshopItem;
    }


    /**
     * 生成初始的赠送物件
     */
    private List<Long> createStartItems(int levelPS, int activityId) {
        List<Long> itemIdList = new ArrayList<>();
        long time = System.currentTimeMillis();
        for (int i = 0; i < PawnshopMgr.config.goodsIdInitList.size(); i++) {
            long itemId = time + i;
            String goodsId = PawnshopMgr.config.goodsIdInitList.get(i);
            if (createItem(levelPS, activityId, goodsId, itemId)) {
                itemIdList.add(itemId);
            }
        }
        return itemIdList;
    }

    /**
     * 生成物件
     */
    private boolean createItem(int levelPS, int activityId, String goodsConfig, long itemId) {
        ConfPawnshop confPawnshop = PawnshopMgr.config.getConfPawnshop(levelPS);
        if (confPawnshop == null) {
            return false;
        }
        List<Integer> arrList = StringUtils.stringToIntegerList(goodsConfig, ";");
        Integer lv = arrList.get(0);
        Integer goodsId = arrList.get(1);
        Integer ra = arrList.get(2);
        Integer status = arrList.get(3);
        PawnshopItem item = new PawnshopItem();
        item.setItemId(itemId);
        item.setGoodsId(goodsId);
        item.setStoneGoodsId(0);
        item.setStoneLv(0);
        item.setLevel(lv);
        item.setRarity(ra);
        item.setStatus(status);
        item.setCoinBuy(0);
        ConfPawnshopItem confPawnshopItem = PawnshopMgr.config.getConfPawnshopItem(goodsId);
        if (confPawnshopItem.getType() != ePawnshopItemType.Gemstone.getValue()) {
            item.setAffixSn1(PawnshopMgr.config.affixSnRangeMap.get(1).random());
        }
        if (PawnshopMgr.randomSn2() && confPawnshopItem.getType() != ePawnshopItemType.Gemstone.getValue()) {
            int sn2 = PawnshopMgr.config.affixSnRangeMap.get(2).random();
            item.setAffixSn2(sn2);
        }
        item.setAffixSn3(0);
        item.setAffixSn4(0);
        long basePrice = PawnshopMgr.calcBasePrice(lv);
        item.setBasePrice(basePrice);
        item.setEventAffixAddition(0);
        item.setPersonAffixAddition(0);
        item.setStatusEffectPrice(PawnshopMgr.getStatusEffectPrice(status));
        item.setDescNo(PawnshopMgr.randomItemDesc(goodsId));
        UserPawnshopItem userPawnshopItem = new UserPawnshopItem();
        userPawnshopItem.setUserId(player.getUserId());
        userPawnshopItem.setActivityId(activityId);
        userPawnshopItem.setItemId(itemId);
        userPawnshopItem.setPawnshopItem(item);
        userPawnshopItem.setRepairTimes(0);
        userPawnshopItem.setFakeStar(item.getFakeStar());
        userPawnshopItem.setOpReceptionNum(0);
        userPawnshopItem.setOpStatus(ePawnshopOpStatus.Default.getValue());
        userPawnshopItem.setDescNo(item.getDescNo());
        userPawnshopItem.setInsertOption();
        addItem(userPawnshopItem, eLogMoneyType.PawnshopDefault.getValue());
        return true;
    }

    public void addItem(UserPawnshopItem userPawnshopItem, int way) {
        if (!userPawnshopItemMap.containsKey(userPawnshopItem.getItemId())) {
            userPawnshopItem.setUserId(getUserId());
            userPawnshopItem.setActivityId(getActivityId());
            userPawnshopItem.setInsertOption();
            userPawnshopItemMap.put(userPawnshopItem.getItemId(), userPawnshopItem);

            long coinValuation = PawnshopMgr.calcItemValuationPrice(userPawnshopItem.getBasePrice(), userPawnshopItem.getRarity(),
                    userPawnshopItem.getStatusEffectPrice(), userPawnshopItem.getEventAffixAddition(), userPawnshopItem.getPersonAffixAddition(),
                    userPawnshop.getPoliticsAddition(), getModValue());
            LogMgr.addLogPawnshopItem(getActivityId(), player.getUserId(), userPawnshopItem.getItemId(), userPawnshopItem.getGoodsId(),
                    userPawnshopItem.getCoinBuy(), coinValuation, way);
        }
    }

    /**
     * 初始化系统，功能解锁时调用
     */
    public void initSystem() {
        int activityId = PawnshopMgr.getShowTimeActivityId();
        if (activityId == 0) {
            // 没有活动
            userPawnshop = null;
            return;
        }
        if (userPawnshop == null) {
            // 初始化玩家数据
            initUserData();
        }
        // 同步体力
        loginSendPower();
    }

    /**
     * 同步当铺基础数据
     */
//    public void syncPawnshopBasicsData() {
//        if (!PawnshopMgr.isActivityInShowTime()) {
//            return;
//        }
//        PawnshopProto.PawnshopBasicsDataMsg.Builder msg = PawnshopPb.parsePawnshopBasicsDataMsg(userPawnshop);
//        if (null != msg) {
//            player.sendChannelPacket(Protocol.U_PAWNSHOP_SYNC, msg);
//        }
//    }

    /**
     * 同步当铺基础数据
     */
    public void loginSendPower() {
        if (!PawnshopMgr.isActivityInShowTime()) {
            return;
        }
        calcPower();
        syncPower();
    }

    /**
     * 获得当铺币
     *
     * @param
     */
    public void coinReward(long coin, int way) {
        long oldCoin = userPawnshop.getCoinUsable();
        userPawnshop.setCoinUsable(userPawnshop.getCoinUsable() + coin);
        notifyScoreChange();
        LogMgr.addLogPawnshopCoin(getActivityId(), player.getUserId(), false, coin, oldCoin, userPawnshop.getCoinUsable(), way);
    }

    /**
     * 消耗当铺币
     *
     * @param
     */
    public int coinCost(long coin, int way) {
        if (userPawnshop.getCoinUsable() < coin) {
            return GameErrorCode.E_PAWNSHOP_COIN_NOT_ENOUGH;
        }
        long oldCoin = userPawnshop.getCoinUsable();
        userPawnshop.setCoinUsable(userPawnshop.getCoinUsable() - coin);
        notifyScoreChange();
        LogMgr.addLogPawnshopCoin(getActivityId(), player.getUserId(), false, coin, oldCoin, userPawnshop.getCoinUsable(), way);
        return 0;
    }

    /**
     * 获取总财富
     *
     * @return
     */
    public long getTotalWealth() {
        long totalWealth = 0;
        if (null != userPawnshop) {
            totalWealth = userPawnshop.getCoinUsable();
        }
        totalWealth += getItemWealth();
        return totalWealth;
    }

    /**
     * 获取指定的物件JSON数据
     *
     * @param itemId
     * @return
     */
    public PawnshopItem getPawnshopItemJSON(long itemId) {
        PawnshopItem itemJSON = null;
        for (PawnshopItem json : userPawnshopEvent.getItemList()) {
            if (json != null && json.getItemId() == itemId) {
                itemJSON = json;
                break;
            }
        }
        return itemJSON;
    }

    /**
     * 获取首个物件JSON数据
     *
     * @param
     * @return
     */
    public PawnshopItem getPawnshopItemJSON() {
        PawnshopItem itemJSON = null;
        if (!userPawnshopEvent.getItemList().isEmpty()) {
            itemJSON = userPawnshopEvent.getItemList().get(0);
        }
        return itemJSON;
    }


    public PawnshopBidResult bid(int index) {
        if (userPawnshopEvent == null || !userPawnshop.isReception()) {
            return new PawnshopBidResult(GameErrorCode.E_PAWNSHOP_NOT_RECEPTION);
        }
        if (index == -1) {
            afterReception();
            return new PawnshopBidResult(0);
        }
        return eventBid(index);
    }

    /**
     * 出价
     *
     * @param index
     * @return
     */
    private PawnshopBidResult eventBid(int index) {

        if (userPawnshopEvent.getStatus() == ePawnshopEventStatusType.FIXED_PRICE.getValue()) {
            return new PawnshopBidResult(GameErrorCode.E_PAWNSHOP_FIXED_PRICE_CAN_NOT_BID);
        }

        if (userPawnshopEvent.getStatus() == ePawnshopEventStatusType.GIVE_UP.getValue()) {
            return new PawnshopBidResult(GameErrorCode.E_PAWNSHOP_CUSTOMER_GIVE_UP);
        }

        if (userPawnshopEvent.getStatus() == ePawnshopEventStatusType.DEAL.getValue()) {
            return new PawnshopBidResult(GameErrorCode.E_PAWNSHOP_DEAL);
        }

        List<PawnshopBidPrice> priceList = userPawnshopEvent.getPriceList();
        if (index >= priceList.size()) {
            return new PawnshopBidResult(GameErrorCode.E_PAWNSHOP_EVENT_ERROR);
        }
        PawnshopBidPrice pawnshopBidPrice = priceList.get(index);
        userPawnshopEvent.setPatient(userPawnshopEvent.getPatient() - pawnshopBidPrice.getReducePatient());

        int randomNum = random.next(0, 100);
        int probability = pawnshopBidPrice.getProbability();
        ePawnshopEventStatusType status;
        userPawnshopEvent.setUserBid(pawnshopBidPrice.getPrice());
        if (randomNum < probability && buyEventHasEnoughMoney(pawnshopBidPrice)) {
            // 成交
            status = ePawnshopEventStatusType.DEAL;
        } else {
            if (userPawnshopEvent.getPatient() <= 0) {
                //没有耐心 放弃了
                status = ePawnshopEventStatusType.GIVE_UP;
            } else {
                status = ePawnshopEventStatusType.NORMAL;
                resetBidPriceList();
            }
        }
        userPawnshopEvent.setStatus(status.getValue());
        return new PawnshopBidResult(pawnshopBidPrice.getPrice(), userPawnshopEvent.getStatus(), userPawnshopEvent.getPatient(), userPawnshopEvent.getPriceList());

    }

    private boolean buyEventHasEnoughMoney(PawnshopBidPrice pawnshopBidPrice) {
        if (userPawnshopEvent.getType() == ePawnshopEventType.Buy.getValue() && userPawnshop.getCoinUsable() < pawnshopBidPrice.getPrice()) {
            return false;
        }
        return true;
    }


    /**
     * 接待
     *
     * @return
     */
    public PawnshopReceptionResult reception(int eventType) {
        PawnshopReceptionResult receptionResult = new PawnshopReceptionResult();
        if (!PawnshopMgr.isActivityInTime()) {// 非活动时间内
            receptionResult.setRet(GameErrorCode.E_ACTIVITY_OVER_TIME);
            return receptionResult;
        }
        int staminaCost = PawnshopMgr.config.getStaminaCost(userPawnshop.getLevel());
        if (userPawnshop.isReception()) {// 顾客已接待过
            receptionResult.setRet(GameErrorCode.E_PAWNSHOP_HAS_RECEPTION);
            return receptionResult;
        }
        //计算一下体力
        calcPower();
        if (userPawnshop.getStaminaUsable() < staminaCost) {// 接待体力不足
            receptionResult.setRet(GameErrorCode.E_PAWNSHOP_STAMINA_COST);
            return receptionResult;
        }
        // 接待成功，扣体力
        int staminaUsable = userPawnshop.getStaminaUsable() - staminaCost;
        userPawnshop.setStaminaUsable(staminaUsable);
        syncPower();
        createNewEvent(eventType);
        receptionResult.setEvent(userPawnshopEvent);
        userPawnshop.setReception(true);
        uploadPowerCostToCross(userPawnshop.getActivityId(), staminaCost);
        Property reward = new Property(PawnshopMgr.config.scoreGoodsId, BigInteger.valueOf(PawnshopMgr.config.staminaScore * staminaCost));
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.Activity, eLogMoneyType.PawnshopReceptionReward);
        receptionResult.setReward(PropertyHelper.parsePropertyToString(reward));
        return receptionResult;
    }

    private void uploadPowerCostToCross(int activityId, int staminaCost) {
        PawnshopProto.PawnshopCrossUploadPowerMsg.Builder msg = PawnshopProto.PawnshopCrossUploadPowerMsg.newBuilder();
        msg.setActivityId(activityId);
        msg.setPower(staminaCost);
        YanQuMessage message = YanQuMessageUtils.buildMessage(CrossProtocol.C_CROSS_PAWNSHOP_UPLOAD_POWER, msg);
        GamePlayerMgr.sendPacket(0, message);
    }

    /**
     * 获取物件
     *
     * @param itemId
     * @return
     */
    public UserPawnshopItem getUserPawnshopItem(long itemId) {
        return userPawnshopItemMap.get(itemId);
    }

    /**
     * 修复物件
     *
     * @return
     */
    public int repairItem(long itemId) {
        if (!PawnshopMgr.isActivityInTime()) {// 非活动时间内
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        if (null == userPawnshop) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        UserPawnshopItem userItem = getUserPawnshopItem(itemId);
        if (null == userItem) {
            return GameErrorCode.E_PAWNSHOP_NOT_ITEM;
        }
        int repairLv = userPawnshop.getStaffLv(ePawnshopStaffType.Repairer.getValue());
        if (repairLv < 1) {
            return GameErrorCode.E_PAWNSHOP_NO_RECRUIT_REPAIRER;
        }
        ConfPawnshopItem confPawnshopItem = PawnshopMgr.config.getConfPawnshopItem(userItem.getGoodsId());
        if (null == confPawnshopItem) {
            return GameErrorCode.E_PAWNSHOP_ITEM_CONFIG_ERROR;
        }
        if (confPawnshopItem.getType() == ePawnshopItemType.Gemstone.getValue()) {
            return GameErrorCode.E_PAWNSHOP_GEMSTONE_CANNOT_REPAIR;
        }
        if (userItem.getOpStatus() == ePawnshopOpStatus.Fake.getValue()) {
            return GameErrorCode.E_PAWNSHOP_ITEM_FAKE_STATUS;
        }
        if (userItem.getOpStatus() == ePawnshopOpStatus.Hock.getValue()) {
            return GameErrorCode.E_PAWNSHOP_ITEM_HOCK_STATUS;
        }
        if (!PawnshopMgr.config.itemStatusCanRepair(userItem.getStatus())) {
            return GameErrorCode.E_PAWNSHOP_ITEM_STATUS_CANNOT_REPAIR;
        }
        int opCount = getItemCountByOpStatus(ePawnshopOpStatus.Repair.getValue());
        if (PawnshopMgr.config.isOpItemCountOver(opCount, ePawnshopStaffType.Repairer.getValue(), repairLv)) {
            return GameErrorCode.E_PAWNSHOP_FAKE_COUNT_OVER;
        }
        userItem.setOpReceptionNum(userPawnshop.getReceptionNum());
        userItem.setOpStatus(ePawnshopOpStatus.Repair.getValue());
        return 0;
    }

    /**
     * 伪造物件
     *
     * @return
     */
    public int fakeItem(long itemId) {
        if (!PawnshopMgr.isActivityInTime()) {// 非活动时间内
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        if (null == userPawnshop) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        UserPawnshopItem userItem = getUserPawnshopItem(itemId);
        if (null == userItem) {
            return GameErrorCode.E_PAWNSHOP_NOT_ITEM;
        }
        int fakeLv = userPawnshop.getStaffLv(ePawnshopStaffType.Faker.getValue());
        if (fakeLv < 1) {
            return GameErrorCode.E_PAWNSHOP_NO_RECRUIT_FAKER;
        }
        if (userItem.getAffixSn3() > 0 || userItem.getAffixSn4() > 0) {
            return GameErrorCode.E_PAWNSHOP_ITEM_SPECIAL_EVENT_NOT_FAKE;
        }
        if (userItem.getFakeStar() > 0) {
            return GameErrorCode.E_PAWNSHOP_ITEM_ALREADY_FAKE;
        }
        ConfPawnshopItem confPawnshopItem = PawnshopMgr.config.getConfPawnshopItem(userItem.getGoodsId());
        if (null == confPawnshopItem) {
            return GameErrorCode.E_PAWNSHOP_ITEM_CONFIG_ERROR;
        }
        if (confPawnshopItem.getType() == ePawnshopItemType.Gemstone.getValue()) {
            return GameErrorCode.E_PAWNSHOP_GEMSTONE_CANNOT_FAKE;
        }
        if (userItem.getOpStatus() == ePawnshopOpStatus.Repair.getValue()) {
            return GameErrorCode.E_PAWNSHOP_ITEM_REPAIR_STATUS;
        }
        if (userItem.getOpStatus() == ePawnshopOpStatus.Hock.getValue()) {
            return GameErrorCode.E_PAWNSHOP_ITEM_HOCK_STATUS;
        }
        int opCount = getItemCountByOpStatus(ePawnshopOpStatus.Fake.getValue());
        if (PawnshopMgr.config.isOpItemCountOver(opCount, ePawnshopStaffType.Faker.getValue(), fakeLv)) {
            return GameErrorCode.E_PAWNSHOP_FAKE_COUNT_OVER;
        }
        userItem.setOpReceptionNum(userPawnshop.getReceptionNum());
        userItem.setOpStatus(ePawnshopOpStatus.Fake.getValue());
        return 0;
    }

    /**
     * 洗脑
     * 说好只能洗脑一次的，如果改成多次，陈煌要摆桌
     *
     * @return
     */
    public PawnshopProto.PawnshopBrainwashRespMsg.Builder brainwash() {
        PawnshopProto.PawnshopBrainwashRespMsg.Builder msg = PawnshopProto.PawnshopBrainwashRespMsg.newBuilder();
        msg.setStatus(userPawnshopEvent.getStatus());
        if (userPawnshopEvent.getWashTime() > 0) {
            msg.setRet(GameErrorCode.E_PAWNSHOP_BRAINWASH_ALREADY);
            return msg;
        }
        if (userPawnshopEvent.getStatus() != ePawnshopEventStatusType.GIVE_UP.getValue()) {
            msg.setRet(GameErrorCode.E_PAWNSHOP_BRAINWASH_ERROR_STATUS);
            return msg;
        }

        userPawnshop.setWashTimes(userPawnshop.getWashTimes() + 1);
        userPawnshopEvent.setWashTime(1);
        userPawnshopEvent.setStatus(ePawnshopEventStatusType.NORMAL.getValue());
        userPawnshopEvent.setPatient(userPawnshopEvent.getPatient() + PawnshopMgr.getBrainwashAddPatient(userPawnshop));

        resetBidPriceList();

        msg.setRet(0);
        msg.setStatus(ePawnshopEventStatusType.NORMAL.getValue());
        msg.setIsWash(true);
        msg.setPatient(userPawnshopEvent.getPatient());
        for (PawnshopBidPrice price : userPawnshopEvent.getPriceList()) {
            msg.addPriceList(PawnshopPb.parseBidPrice(price));
        }
        return msg;
    }

    /**
     * 重新给出出价列表
     */
    private void resetBidPriceList() {
        if (userPawnshopEvent.getType() == ePawnshopEventType.Sell.getValue()) {
            PawnshopMgr.sellEventResetPrice(userPawnshop, userPawnshopEvent);
            List<PawnshopBidPrice> bidPriceList = PawnshopMgr.sellBidPriceList(userPawnshop, userPawnshopEvent);
            userPawnshopEvent.setPriceList(bidPriceList);
        } else {
            PawnshopMgr.buyEventResetPrice(userPawnshop, userPawnshopEvent);
            List<PawnshopBidPrice> bidPriceList = PawnshopMgr.buyBidPriceList(userPawnshop, userPawnshopEvent);
            userPawnshopEvent.setPriceList(bidPriceList);
        }
    }

    private boolean overTotalBrainwashTimes() {
        int washTimes = userPawnshop.getWashTimes();
        int staffLv = userPawnshop.getStaffLv(ePawnshopStaffType.Brainwasher.getValue());
        int maxTimes = PawnshopMgr.config.getStaffOpEffect(ePawnshopStaffType.Brainwasher.getValue(), staffLv);
        return washTimes >= maxTimes;
    }

    /**
     * 获取操作中的物件数量
     *
     * @param opStatus
     * @return
     */
    private int getItemCountByOpStatus(int opStatus) {
        int count = 0;
        for (UserPawnshopItem userItem : userPawnshopItemMap.values()) {
            if (userItem.getOpStatus() == opStatus) {
                count++;
            }
        }
        return count;
    }

    /**
     * 检测物件操作状态
     */
    public List<UserPawnshopNotify> checkItemOpStatus(int staffType) {
        List<UserPawnshopItem> syncList = new ArrayList<>();
        List<UserPawnshopNotify> notifyList = new ArrayList<>();
        for (UserPawnshopItem userItem : userPawnshopItemMap.values()) {
            if (userItem.getOpStatus() == ePawnshopOpStatus.Repair.getValue() &&
                    (0 == staffType || ePawnshopStaffType.Repairer.getValue() == staffType)) {//修复
                int opReceptionNum = userPawnshop.getReceptionNum() - userItem.getOpReceptionNum();
                Integer rDay = PawnshopMgr.config.getRarityCostDay(userItem.getRarity());
                if (null == rDay) {//找不到对应配置
                    continue;
                }
                int needDays = rDay - PawnshopMgr.config.getStaffOpEffect(ePawnshopStaffType.Repairer.getValue(),
                        userPawnshop.getStaffLv(ePawnshopStaffType.Repairer.getValue()));
                int needReceptionNum = needDays * PawnshopMgr.config.receptionDay;
                if (opReceptionNum >= needReceptionNum) {//修复完成
                    //修复完成
                    int oldItemStatus = userItem.getStatus();
                    long oldCoinValuation = PawnshopMgr.calcItemValuationPrice(userItem.getBasePrice(), userItem.getRarity(), userItem.getStatusEffectPrice(),
                            userItem.getEventAffixAddition(), userItem.getPersonAffixAddition(), userPawnshop.getPoliticsAddition(), getModValue());
                    int itemStatus = PawnshopMgr.getItemRepairStatus(userPawnshop.getStaffLv(ePawnshopStaffType.Repairer.getValue()));
                    int statusEffectPrice = PawnshopMgr.getStatusEffectPrice(itemStatus);
                    userItem.setStatus(itemStatus);
                    userItem.setStatusEffectPrice(statusEffectPrice);
                    userItem.setOpStatus(ePawnshopOpStatus.Default.getValue());
                    //增加通知
                    UserPawnshopNotify notify = addNotify(ePawnshopNotifyType.RepairFinish.getValue(), userItem, oldItemStatus, oldCoinValuation, 0);
                    notifyList.add(notify);
                    syncList.add(userItem);
                    long coinValuation = PawnshopMgr.calcItemValuationPrice(userItem.getBasePrice(), userItem.getRarity(), userItem.getStatusEffectPrice(),
                            userItem.getEventAffixAddition(), userItem.getPersonAffixAddition(), userPawnshop.getPoliticsAddition(), getModValue());
                    LogMgr.addLogPawnshopRepair(getActivityId(), player.getUserId(), userItem.getItemId(), userItem.getOpReceptionNum(), needDays,
                            oldItemStatus, itemStatus, oldCoinValuation, coinValuation);
                }
            } else if (userItem.getOpStatus() == ePawnshopOpStatus.Fake.getValue() &&
                    (0 == staffType || ePawnshopStaffType.Faker.getValue() == staffType)) {//伪造
                int opReceptionNum = userPawnshop.getReceptionNum() - userItem.getOpReceptionNum();
                Integer rDay = PawnshopMgr.config.getRarityCostDay(userItem.getRarity());
                if (null == rDay) {//找不到对应配置
                    continue;
                }
                int needDays = rDay - PawnshopMgr.config.getStaffOpEffect(ePawnshopStaffType.Faker.getValue(),
                        userPawnshop.getStaffLv(ePawnshopStaffType.Faker.getValue()));
                int needReceptionNum = needDays * PawnshopMgr.config.getReceptionDay();
                if (opReceptionNum >= needReceptionNum) {//伪造完成
                    //伪造完成
                    int fakeStar = PawnshopMgr.getItemFakeStar(userPawnshop.getStaffLv(ePawnshopStaffType.Faker.getValue()));
                    long oldCoinValuation = PawnshopMgr.calcItemValuationPrice(userItem.getBasePrice(), userItem.getRarity(), userItem.getStatusEffectPrice(),
                            userItem.getEventAffixAddition(), userItem.getPersonAffixAddition(), userPawnshop.getPoliticsAddition(), getModValue());
                    int sn3 = PawnshopMgr.config.affixSnRangeMap.get(3).random();
                    int sn4 = PawnshopMgr.randomSn4(userItem.getGoodsId());
                    int fakeAffix = PawnshopMgr.getFakeAffix();
                    if (fakeAffix == 0) {
                        //人物词条
                        userItem.setAffixSn3(sn3);
                        userItem.setPersonAffixAddition(PawnshopMgr.randomPersonalAdditionByFakeStar(fakeStar));
                    } else if (fakeAffix == 1) {
                        //事件词条
                        userItem.setAffixSn4(sn4);
                        userItem.setEventAffixAddition(PawnshopMgr.randomEventAdditionByFakeStar(fakeStar));
                    } else {
                        //人物 + 事件 词条
                        userItem.setAffixSn3(sn3);
                        userItem.setPersonAffixAddition(PawnshopMgr.randomPersonalAdditionByFakeStar(fakeStar));
                        userItem.setAffixSn4(sn4);
                        userItem.setEventAffixAddition(PawnshopMgr.randomEventAdditionByFakeStar(fakeStar));
                    }
                    userItem.setFakeStar(fakeStar);
                    userItem.setOpStatus(ePawnshopOpStatus.Default.getValue());
                    //增加通知
                    UserPawnshopNotify notify = addNotify(ePawnshopNotifyType.FakeFinish.getValue(), userItem, userItem.getStatus(),
                            oldCoinValuation, 0);
                    notifyList.add(notify);
                    syncList.add(userItem);
                    long coinValuation = PawnshopMgr.calcItemValuationPrice(userItem.getBasePrice(), userItem.getRarity(), userItem.getStatusEffectPrice(),
                            userItem.getEventAffixAddition(), userItem.getPersonAffixAddition(), userPawnshop.getPoliticsAddition(), getModValue());
                    LogMgr.addLogPawnshopFake(getActivityId(), player.getUserId(), userItem.getItemId(), userItem.getOpReceptionNum(), needDays,
                            fakeStar, oldCoinValuation, coinValuation);
                }
            } else if (userItem.getOpStatus() == ePawnshopOpStatus.Hock.getValue() && 0 == staffType) {//典当
                int opReceptionNum = userPawnshop.getReceptionNum() - userItem.getOpReceptionNum();
                if (opReceptionNum >= PawnshopMgr.config.getHockDays() * PawnshopMgr.config.getReceptionDay()) {//典当时间到
                    if (PawnshopMgr.isHockRedemption()) {//典当赎回
                        long redemptionPrice = PawnshopMgr.getHockRedemptionPrice(userItem.getCoinBuy());
                        //加钱
                        coinReward(redemptionPrice, eLogMoneyType.PawnshopHockRedemption.getValue());
                        //卖物件
                        removeItem(userItem.getItemId(), eLogMoneyType.PawnshopHockRedemption.getValue());
                        long oldCoinValuation = PawnshopMgr.calcItemValuationPrice(userItem.getBasePrice(), userItem.getRarity(), userItem.getStatusEffectPrice(),
                                userItem.getEventAffixAddition(), userItem.getPersonAffixAddition(), userPawnshop.getPoliticsAddition(), getModValue());
                        //增加通知
                        UserPawnshopNotify notify = addNotify(ePawnshopNotifyType.HockRedemption.getValue(), userItem, userItem.getStatus(),
                                oldCoinValuation, redemptionPrice);
                        notifyList.add(notify);
                        syncList.add(userItem);
                    } else {//典当放弃
                        userItem.setOpStatus(ePawnshopOpStatus.Default.getValue());
                        //增加通知
                        long oldCoinValuation = PawnshopMgr.calcItemValuationPrice(userItem.getBasePrice(), userItem.getRarity(), userItem.getStatusEffectPrice(),
                                userItem.getEventAffixAddition(), userItem.getPersonAffixAddition(), userPawnshop.getPoliticsAddition(), getModValue());
                        UserPawnshopNotify notify = addNotify(ePawnshopNotifyType.HockGiveUp.getValue(), userItem, userItem.getStatus(),
                                oldCoinValuation, 0);
                        notifyList.add(notify);
                        syncList.add(userItem);
                    }
                }
            }
        }
        return notifyList;
    }

    /**
     * 增加体力
     *
     * @param goodsInfo
     * @param count
     */
    public void addPower(GoodsInfo goodsInfo, long count) {
        long addCount = goodsInfo.getParamList().get(0).longValue() * count;
        if (null != userPawnshop) {
            calcPower();
            userPawnshop.setStaminaUsable((int) (userPawnshop.getStaminaUsable() + addCount));
            syncPower();
        }
    }

    /**
     * 计算体力
     */
    public void calcPower() {
        if (null == userPawnshop) {
            return;
        }
        long nowTime = System.currentTimeMillis() / 1000;
        long lastRestoreTime = userPawnshop.getLastRestoreTime();
        int maxPower = PawnshopMgr.config.staminaMax;
        int powerRestoreTime = PawnshopMgr.config.staminaTime;
        if (userPawnshop.getStaminaUsable() < maxPower) {
            //恢复次数
            int restoreTimes = (int) ((nowTime - lastRestoreTime) / powerRestoreTime);
            if (restoreTimes < 0) {
                restoreTimes = 0;
            }
            int power = userPawnshop.getStaminaUsable();
            // 当前值 + 恢复指 如果超过最大值
            if (restoreTimes + power >= maxPower) {
                power = maxPower;
                userPawnshop.setLastRestoreTime(nowTime);
            } else {
                power = power + restoreTimes;
                userPawnshop.setLastRestoreTime(lastRestoreTime + powerRestoreTime * restoreTimes);
            }
            userPawnshop.setStaminaUsable(power);
        } else {
            userPawnshop.setLastRestoreTime(nowTime);
        }
    }

    /**
     * 同步体力
     */
    public void syncPower() {
        if (null != userPawnshop) {
            PawnshopProto.PawnshopStaminaSyncMsg.Builder syncMsg = PawnshopProto.PawnshopStaminaSyncMsg.newBuilder();
            syncMsg.setStaminaUsable(userPawnshop.getStaminaUsable());
            syncMsg.setLastRestoreTime(userPawnshop.getLastRestoreTime());
            player.sendPacket(Protocol.U_PAWNSHOP_SYNC_STAMINA, syncMsg);
        }
    }

    // 确认：0放弃，1确认
    public int confirmSell(int confirm) {
        PawnshopProto.PawnshopEventSellConfirmRespMsg.Builder msg = PawnshopProto.PawnshopEventSellConfirmRespMsg.newBuilder();
        int ret = 0;
        if (userPawnshopEvent.getType() == ePawnshopEventType.Sell.getValue()) {
            if (confirm == 0) {
                if (userPawnshopEvent.getIsFake()) {
                    //忽悠
                    if (foolCustomer()) {
                        userPawnshopEvent.setIsFake(false);
                        msg.setIsFoolSucc(true);
                    } else {
                        long itemId = userPawnshopEvent.getItemList().get(0).getItemId();
                        UserPawnshopItem item = removeItem(itemId, eLogMoneyType.PawnshopSellItem.getValue());
                        msg.setItemId(item.getItemId());
                        afterReception();
                    }
                } else {
                    afterReception();
                }
            } else if (confirm == 1) {
                ret = canSell();
                if (ret == 0) {
                    PawnshopItem pawnshopItem = userPawnshopEvent.getItemList().get(0);
                    long itemId = pawnshopItem.getItemId();
                    UserPawnshopItem item = removeItem(itemId, eLogMoneyType.PawnshopSellItem.getValue());
                    if (userPawnshopEvent.getIsFake()) {
                        //是假货
                        long valuationPrice = PawnshopMgr.calcItemValuationPrice(pawnshopItem, userPawnshop.getPoliticsAddition(), getModValue());
                        long reward = (long) Math.ceil(valuationPrice * PawnshopMgr.config.eventSellFakeBuyRate / 1000.0);
                        coinReward(reward, eLogMoneyType.PawnshopSellItem.getValue());
                        msg.setGoodsId(item.getGoodsId());
                        msg.setCoinCost(reward);
                    } else {
                        long userBid = userPawnshopEvent.getUserBid();
                        coinReward(userBid, eLogMoneyType.PawnshopSellItem.getValue());
                        msg.setGoodsId(item.getGoodsId());
                        msg.setCoinCost(userBid);
                    }
                    afterReception();
                } else {
                    afterReception();
                }
            }
        } else {
            ret = GameErrorCode.E_PAWNSHOP_EVENT_ERROR;
        }
        msg.setRet(ret);
        msg.setConfirm(confirm);
        player.sendPacket(Protocol.U_PAWNSHOP_EVENT_SELL_CONFIRM, msg);
        return 0;
    }

    private UserPawnshopItem removeItem(long itemId, int way) {
        UserPawnshopItem item = userPawnshopItemMap.get(itemId);
        item.setOpStatus(ePawnshopOpStatus.SellOut.getValue());
        long coinValuation = PawnshopMgr.calcItemValuationPrice(item.getBasePrice(), item.getRarity(),
                item.getStatusEffectPrice(), item.getEventAffixAddition(), item.getPersonAffixAddition(),
                userPawnshop.getPoliticsAddition(), getModValue());
        LogMgr.addLogPawnshopItem(getActivityId(), player.getUserId(), itemId, item.getGoodsId(), item.getCoinBuy(), coinValuation, way);
        return item;
    }

    private boolean foolCustomer() {
        return PawnshopMgr.isFoolSuccess();
    }

    private int canSell() {
        if (userPawnshopEvent == null) {
            return GameErrorCode.E_PAWNSHOP_EVENT_ERROR;
        }
        return 0;
    }

    public int confirmBuy(int confirm) {
        PawnshopProto.PawnshopEventBuyConfirmRespMsg.Builder msg = PawnshopProto.PawnshopEventBuyConfirmRespMsg.newBuilder();
        int ret = 0;
        if (userPawnshopEvent.getType() == ePawnshopEventType.Buy.getValue()) {
            if (confirm == 0) {
                if (userPawnshopEvent.getIsFake()) {
                    int addPower = PawnshopMgr.getRefuseFakeAddPower(userPawnshop.getLevel());
                    userPawnshop.setStaminaUsable(userPawnshop.getStaminaUsable() + addPower);
                    msg.setStaminaReward(addPower);
                }
                afterReception();
            } else if (confirm == 1) {
                PawnshopItem pawnshopItem = userPawnshopEvent.getItemList().get(0);
                UserPawnshopItem item = new UserPawnshopItem();
                item.setItemId(System.currentTimeMillis());
                item.setPawnshopItem(pawnshopItem);
                long userBid = userPawnshopEvent.getUserBid();
                if (userPawnshopEvent.getIsFake()) {
                    item.setFakeStar(pawnshopItem.getFakeStar());
                    userBid = (long) Math.nextUp(PawnshopMgr.calcItemValuationPrice(pawnshopItem, userPawnshop.getPoliticsAddition(), getModValue()) * PawnshopMgr.config.eventBuyFakeBuyRate / 1000);
                }

                ret = coinCost(userBid, eLogMoneyType.PawnshopBuyItem.getValue());
                if (ret == 0) {
                    item.setCoinBuy(userBid);
                    addItem(item, eLogMoneyType.PawnshopBuyItem.getValue());
                    msg.setGoodsId(pawnshopItem.getGoodsId());
                    msg.setCoinCost(userBid);
                    afterReception();
                } else {
                    afterReception();
                }
            }
        } else {
            ret = GameErrorCode.E_PAWNSHOP_EVENT_ERROR;
        }
        msg.setConfirm(confirm);
        msg.setRet(ret);
        player.sendPacket(Protocol.U_PAWNSHOP_EVENT_BUY_CONFIRM, msg);
        return 0;
    }

    /**
     * 触发时事
     */
    public void checkPolitics() {
        if (null == userPawnshop) {
            return;
        }
        int startNum = PawnshopMgr.config.getPoliticsStartDay() * PawnshopMgr.config.getReceptionDay();
        if (userPawnshop.getReceptionNum() % PawnshopMgr.config.getReceptionDay() != 0) {//还没过完一天
            return;
        }
        if (userPawnshop.getPoliticsEventId() > 0) {//判断时事结束
            int eventId = userPawnshop.getPoliticsEventId();
            int duringDay = 0;
            ConfPawnshopEvent confPawnshopEvent = PawnshopMgr.config.getConfPawnshopEvent(eventId);
            if (null != confPawnshopEvent) {
                duringDay = confPawnshopEvent.getDuring();
            }
            int receptionNum = duringDay * PawnshopMgr.config.getReceptionDay();
            receptionNum += userPawnshop.getPoliticsStartReceptionNum();
            if (userPawnshop.getReceptionNum() >= receptionNum) {//到期了
                userPawnshop.setPoliticsAddition(0);
                userPawnshop.setPoliticsStartReceptionNum(0);
                userPawnshop.setPoliticsEventId(0);
                userPawnshop.setPoliticsTriggerRate(PawnshopMgr.config.getPoliticsDefaultRate());
                syncPolitics();
            }
        } else {
            if (userPawnshop.getReceptionNum() >= startNum) {//开始触发时事
                if (PawnshopMgr.isTriggerPolitics(userPawnshop.getPoliticsTriggerRate())) {//触发时事
                    ConfPawnshopEvent confPawnshopEvent = PawnshopMgr.getRandomConfPawnshopEvent();
                    if (null != confPawnshopEvent) {
                        userPawnshop.setPoliticsStartReceptionNum(userPawnshop.getReceptionNum());
                        userPawnshop.setPoliticsAddition(PawnshopMgr.getRandomPoliticsAddition(confPawnshopEvent));
                        userPawnshop.setPoliticsEventId(confPawnshopEvent.getEventId());
                        userPawnshop.setPoliticsRead(false);
                        LogMgr.addLogPawnshopPolitics(getActivityId(), player.getUserId(), userPawnshop.getPoliticsEventId(), userPawnshop.getPoliticsAddition(),
                                userPawnshop.getPoliticsStartReceptionNum(), userPawnshop.getPoliticsTriggerRate());
                    }
                } else {
                    userPawnshop.setPoliticsTriggerRate(userPawnshop.getPoliticsTriggerRate() + PawnshopMgr.config.getPoliticsAddRate());
                }
                syncPolitics();
            }
        }
    }

    public void syncPolitics() {
        //todo 同步时事
    }

    /**
     * 设置时事已读
     *
     * @return
     */
    public int setPoliticsRead() {
        if (!PawnshopMgr.isActivityInTime()) {// 非活动时间内
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        if (null == userPawnshop) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        if (userPawnshop.getPoliticsEventId() == 0) {
            return GameErrorCode.E_PAWNSHOP_NOW_NO_POLITICS;
        }
        userPawnshop.setPoliticsRead(true);
        return 0;
    }

    /**
     * 增加通知
     *
     * @param type
     * @param userPawnshopItem
     * @param oldItemStatus
     * @param oldCoinValuation
     * @param redemptionPrice
     * @return
     */
    private UserPawnshopNotify addNotify(int type, UserPawnshopItem userPawnshopItem, int oldItemStatus, long oldCoinValuation, long redemptionPrice) {
        UserPawnshopNotify data = new UserPawnshopNotify();
        data.setUserId(player.getUserId());
        data.setActivityId(getActivityId());
        data.setType(type);
        data.setItemId(userPawnshopItem.getItemId());
        data.setStatusOld(oldItemStatus);
        data.setRedemptionPrice(redemptionPrice);
        data.setCoinValuationOld(oldCoinValuation);
        data.setNotifyId(curNotifyId.incrementAndGet());
        data.setUserPawnshopItem(userPawnshopItem);
        data.setInsertOption();
        userPawnshopNotifyMap.put(data.getNotifyId(), data);
        return data;
    }

    public int addHockItem(boolean isConfirm) {
        PawnshopProto.PawnshopEventHockConfirmRespMsg.Builder builder = PawnshopProto.PawnshopEventHockConfirmRespMsg.newBuilder();
        int ret = 0;
        if (userPawnshopEvent.getType() == ePawnshopEventType.Hock.getValue()) {
            if (isConfirm) {
                PawnshopItem item = userPawnshopEvent.getItemList().get(0);
                long coinCost = (long) Math.ceil(1.0d * PawnshopMgr.calcItemValuationPrice(item, userPawnshop.getPoliticsAddition(), getModValue()) * PawnshopMgr.config.eventHockBuyRate / 1000);
                ret = coinCost(coinCost, eLogMoneyType.PawnshopHock.getValue());
                if (ret == 0) {
                    UserPawnshopItem userPawnshopItem = new UserPawnshopItem();
                    userPawnshopItem.setPawnshopItem(item);
                    userPawnshopItem.setItemId(System.currentTimeMillis());
                    userPawnshopItem.setOpReceptionNum(userPawnshop.getReceptionNum() + 1);
                    userPawnshopItem.setCoinBuy(coinCost);
                    userPawnshopItem.setOpStatus(ePawnshopOpStatus.Hock.getValue());
                    addItem(userPawnshopItem, eLogMoneyType.PawnshopHock.getValue());
                    afterReception();
                    builder.setGoodsId(item.getGoodsId());
                    builder.setCoinCost(coinCost);
                }
            } else {
                afterReception();
            }
        } else {
            ret = GameErrorCode.E_PAWNSHOP_EVENT_ERROR;
        }
        builder.setRet(ret);
        builder.setIsConfirm(isConfirm);
        player.sendPacket(ClientProtocol.U_PAWNSHOP_EVENT_HOCK_CONFIRM, builder);
        return 0;
    }

    /**
     * 积分变更
     */
    private void notifyScoreChange() {
        if (null == userPawnshop) {
            return;
        }
        player.notifyListener(eGamePlayerEventType.PawnshopScoreRank.getValue(), getTotalWealth());
        player.notifyListener(eGamePlayerEventType.PawnshopScoreCrossRank.getValue(), getTotalWealth());
    }

    /**
     * 当铺升级
     */
    private void checkPawnshopUpgrade() {
        if (null == userPawnshop) {
            return;
        }
        int loopTimes = 1;
        do {
            ConfPawnshop confPawnshop = PawnshopMgr.config.getConfPawnshop(userPawnshop.getLevel());
            if (null == confPawnshop) {
                return;
            }
            if (confPawnshop.getUpgradeMoney() == 0) {//最高级
                return;
            }
            ConfPawnshop nextConfig = PawnshopMgr.config.getConfPawnshop(userPawnshop.getLevel() + 1);
            if (nextConfig == null) {
                return;
            }
            long upgradeMoney = PawnshopMgr.config.getPawnshopUpgradeMoney(userPawnshop.getLevel());
            if (getTotalWealth() >= upgradeMoney) {//达到升级条件
                //发送升级奖励
                coinReward(confPawnshop.getUpgradeReward(), eLogMoneyType.PawnshopUpgradeReward.getValue());
                //加1级
                int oldLv = userPawnshop.getLevel();
                userPawnshop.setLevel(userPawnshop.getLevel() + 1);
                LogMgr.addLogPawnshopUpgrade(getActivityId(), player.getUserId(), oldLv, userPawnshop.getLevel(), userPawnshop.getReceptionNum(),
                        confPawnshop.getUpgradeReward());
            } else {
                break;
            }
            loopTimes++;
            if (loopTimes > 1000) {//防止死循环
                break;
            }
        } while (true);
    }

    /**
     * 员工升级检测
     */
    private void checkStaffUpgrade() {
        if (null == userPawnshop) {
            return;
        }
        int loopTimes = 1;
        Map<Integer, UserPawnshopStaff> syncMap = new ConcurrentHashMap<>();
        do {
            boolean isUpgrade = false;
            for (ePawnshopStaffType staffType : ePawnshopStaffType.values()) {
                UserPawnshopStaff userPawnshopStaff = checkStaffUpgrade(staffType.getValue());
                if (null != userPawnshopStaff) {
                    syncMap.put(staffType.getValue(), userPawnshopStaff);
                    isUpgrade = true;
                }
            }
            if (!isUpgrade) {//都没有升级了
                break;
            }
            loopTimes++;
            if (loopTimes > 1000) {//防止死循环
                break;
            }
        } while (true);
        if (syncMap.size() > 0) {
            PawnshopProto.PawnshopStaffListMsg.Builder listMsg = PawnshopPb.parsePawnshopStaffListMsg(new ArrayList<>(syncMap.values()));
            player.sendPacket(Protocol.U_PAWNSHOP_STAFF_UPGRADE, listMsg);
        }
    }

    /**
     * 员工升级检测
     *
     * @param staffType
     * @return
     */
    private UserPawnshopStaff checkStaffUpgrade(int staffType) {
        int staffLv = userPawnshop.getStaffLv(staffType);
        if (PawnshopMgr.checkStaffCanUpgrade(userPawnshop.getLevel(), staffType, staffLv)) {//升级
            return userPawnshop.addStaffLv(staffType);
        }
        return null;
    }

    public long getItemWealth() {
        long totalWealth = 0;
        for (UserPawnshopItem item : userPawnshopItemMap.values()) {
            if (item.getOpStatus() != ePawnshopOpStatus.SellOut.getValue()) {
                totalWealth += item.getCoinBuy();
            }
        }
        return totalWealth;
    }

    /**
     * 设置通知已读
     */
    public int setNotifyRead(long notifyId) {
        if (!PawnshopMgr.isActivityInTime()) {// 非活动时间内
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        if (null == userPawnshop) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        UserPawnshopNotify userPawnshopNotify = userPawnshopNotifyMap.get(notifyId);
        if (null != userPawnshopNotify) {
            userPawnshopNotify.setIsRead(true);
        }
        return 0;
    }

    /**
     * 获取未读通知
     *
     * @return
     */
    public List<UserPawnshopNotify> getUnReadNotifyList() {
        List<UserPawnshopNotify> dataList = new ArrayList<>();
        for (UserPawnshopNotify notify : userPawnshopNotifyMap.values()) {
            if (!notify.getIsRead()) {
                dataList.add(notify);
            }
        }
        return dataList;
    }

    public List<Long> getItemIdList() {
        List<Long> list = new ArrayList<>();
        for (UserPawnshopItem item : userPawnshopItemMap.values()) {
            if (item.getOpStatus() != ePawnshopOpStatus.SellOut.getValue()) {
                list.add(item.getItemId());
            }
        }
        return list;
    }

    public void getShopLvReward() {
        PawnshopProto.GetShopLvRewardRespMsg.Builder resp = PawnshopProto.GetShopLvRewardRespMsg.newBuilder();
        resp.setRet(GameErrorCode.E_PAWNSHOP_NO_LV_REWARD);
        int lvReward = userPawnshop.getLvReward();
        int level = userPawnshop.getLevel();
        Property reward = new Property();
        for (int i = lvReward; i < level; i++) {
            Property property = PropertyHelper.parseStringToProperty(PawnshopMgr.config.getConfPawnshop(i).getUpgradeOtherReward());
            reward.addProperty(property);
            userPawnshop.setLvReward(i + 1);
            player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.YongAnDang, eLogMoneyType.YongAnDangLvReward);
        }
        if (!reward.isNothing()) {
            resp.setRet(0);
            resp.setReward(PropertyHelper.parsePropertyToString(reward));
        }
        resp.setShopRewardLv(userPawnshop.getLvReward());
        player.sendPacket(Protocol.U_PAWNSHOP_GET_LV_REWARD, resp);
    }
}
